// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v
description: >
  Handler can only return true for non-extensible targets if the given prototype
  is the same as target's prototype
info: |
  [[SetPrototypeOf]] (V)

  12. Let targetProto be ? target.[[GetPrototypeOf]]().
  13. If SameValue(V, targetProto) is false, throw a TypeError exception.
  14. Return true.
features: [Proxy, Reflect, Reflect.setPrototypeOf]
---*/

function Test() {
    var proto = {};
    var target = Object.setPrototypeOf({}, proto);

    Object.preventExtensions(target);

    var proxy;

    proxy = new Proxy(target, {
      setPrototypeOf: function() {
        return true;
      }
    });

    assert.sameValue(
      Reflect.setPrototypeOf(proxy, proto),
      true,
      "prototype arg is the same in target"
    );

    var outro = {};
    proxy = new Proxy(outro, {
      setPrototypeOf: function(t, p) {
        Object.setPrototypeOf(t, p);
        Object.preventExtensions(t);
        return true;
      }
    });

    assert.sameValue(
      Reflect.setPrototypeOf(proxy, proto),
      true,
      "prototype is set to target inside handler trap"
    );
    assert.sameValue(
      Object.getPrototypeOf(outro),
      proto,
      "target has the custom set prototype"
    );
}

// preheat
const NUMBER_OF_PREHEAT = 1;
for (let i = 0; i < NUMBER_OF_PREHEAT; i++) {
    Test();
}

ArkTools.jitCompileAsync(Test);
assert.sameValue(ArkTools.waitJitCompileFinish(Test), true, '[JIT] JIT disabled.');

// test
const NUMBER_OF_TEST = 1; // or 2
for (let i = 0; i < NUMBER_OF_PREHEAT; i++) {
    Test();
}
